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

end

parent 7715277b
No related branches found
No related tags found
No related merge requests found
Pipeline #8498 passed
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
"@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/icons-material": "^5.13.7",
"@mui/material": "^5.8.6" "@mui/material": "^5.8.6",
"recoil": "^0.7.7"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.18.6", "@babel/cli": "^7.18.6",
......
This diff is collapsed.
<html> <html>
<head> <head>
<title> muiBasic </title> <title> sumin's music </title>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
</head> </head>
......
import React from 'react'; import React, { useEffect, useState } from 'react';
import {Box,Tabs,Tab, Typography, AppBar, CssBaseline} from "@mui/material"; import {Box,Tabs,Tab, Typography, AppBar, CssBaseline} from "@mui/material";
import MusicList from "./MusicList";
import Favorites from './Favorites'; import Favorites from './Favorites';
import music_list from "./data";
import SnackMsg from './SnackMsg';
import SearchPage from './SearchPage'; import SearchPage from './SearchPage';
import { SettingsCellRounded } from '@mui/icons-material';
export default function App (){ export default function App (){
const [currentTab,setCurrentTab] = React.useState(0); const [currentTab,setCurrentTab] = React.useState(0);
const [searchResult, setSearchResult] = React.useState([]); const [searchResult, setSearchResult] = React.useState([]);
const [likes, setLikes] = React.useState({}); const [likes, setLikes] = React.useState({});
const [favorites, setFavorites] = React.useState([]);
useEffect(() => {
const fetchLikes = () => {
fetch("/likes")
.then((response)=>response.json())
.then((r)=>{
console.log(r);
setLikes(r);
}).catch(e => console.log('error while getting likes'));
};
fetchLikes();
}, []);
const handleTabChange = (event, newValue)=>{ const handleTabChange = (event, newValue)=>{
setCurrentTab(newValue); setCurrentTab(newValue);
} }
const handleLike = (id, item) => {
const isLiked = likes[id] === true;
setLikes((prevLikes) => ({ ...prevLikes, [id]: !isLiked }));
if(!isLiked){
const updatedFavorites = [...favorites, item];
setFavorites(updatedFavorites);
fetch("/likes", {
method: "POST",
headers: {
"Content-Type" : "application/json",
},
body: JSON.stringify(item),
}).catch((e) => console.log("error while posting likes"));
} else {
const updatedFavorites = favorites.filter(favorite => favorite.collectionId !== id);
setFavorites(updatedFavorites);
fetch(`/likes/${id}`, {
method: "DELETE",
}).catch((e) => console.log("error while deleting"));
}
};
return ( return (
<React.Fragment> <React.Fragment>
<AppBar position ="fixed"> <AppBar position ="fixed">
...@@ -32,10 +70,9 @@ export default function App (){ ...@@ -32,10 +70,9 @@ export default function App (){
</Tabs> </Tabs>
</Box> </Box>
{currentTab == 0 && <SearchPage list={searchResult} onSearch={setSearchResult}/>} {currentTab == 0 && <SearchPage list={searchResult} onSearch={setSearchResult} likes={likes} onLike={handleLike}/>}
{currentTab === 1 && <Favorites list={searchResult} likes={likes} />} {currentTab === 1 && <Favorites list={favorites} likes={likes} onLike={handleLike}/>}
{currentTab == 2 && <Typography align="center" variant='h2'>More</Typography>} {currentTab == 2 && <Typography align="center" variant='h2'>More</Typography>}
</React.Fragment> </React.Fragment>
); );
} }
\ No newline at end of file
import React from 'react'; import React, { useEffect } from 'react';
import { Typography } from '@mui/material';
import MusicList from './MusicList'; import MusicList from './MusicList';
const Favorites = ({ list, likes }) => { const Favorites = ({ list, likes, onLike}) => {
const favoriteList = list.filter(item => likes[item.collectionCensoredName]);
return ( return (
<React.Fragment> <React.Fragment>
<Typography align="center" variant="h2">Favorites</Typography> <MusicList list={list} likes={likes} onLike={onLike} />
{favoriteList.length > 0 ? (
<MusicList list={favoriteList} />
) : (
<Typography align="center" variant="h4">No favorites yet.</Typography>
)}
</React.Fragment> </React.Fragment>
); );
} }
export default Favorites; export default Favorites;
import React from "react"; import React, { useState } from 'react';
import {Card, CardContent,CardActions, Typography,IconButton, Alert} from "@mui/material"; import {Card, CardContent,CardActions, Typography,IconButton, Alert} from "@mui/material";
import {Favorite, FavoriteBorder} from "@mui/icons-material"; import {Favorite, FavoriteBorder} from "@mui/icons-material";
import SnackMsg from "./SnackMsg"; import SnackMsg from "./SnackMsg";
...@@ -19,14 +19,18 @@ const styles={ ...@@ -19,14 +19,18 @@ const styles={
}; };
export default function MusicList ({list}){ export default function MusicList ({list, likes, onLike}){
if (!likes) return null;
const [likes,setLikes] = React.useState({}); let [snackState, setSnackState] = useState({open:false, msg:""});
let [snackState, setSnackState] = React.useState({open:false, msg:""});
const toggleFavorite=(id) => () => { const toggleFavorite=(id, name, item) => () => {
setLikes({...likes, [id]: !likes[id]}); onLike(id, item);
setSnackState({...snackState, open :true, msg:`${id} is clicked`}); setSnackState((prevState) => ({
...prevState,
open: true,
msg: `${name} is clicked`,
}));
} }
const handleSnackbarClose = (event, reason) => { const handleSnackbarClose = (event, reason) => {
...@@ -34,9 +38,12 @@ export default function MusicList ({list}){ ...@@ -34,9 +38,12 @@ export default function MusicList ({list}){
return; return;
} }
setSnackState({open : false, msg : ''}); setSnackState({open : false, msg : ''});
} };
return ( return (
<div>{list.map(item =>{ <div>
{list.map(item =>{
var isLiked = likes.hasOwnProperty(item.collectionId) && likes[item.collectionId] === true;
return ( return (
<Card sx={styles.card} key={item.collectionId}> <Card sx={styles.card} key={item.collectionId}>
<CardContent> <CardContent>
...@@ -45,8 +52,9 @@ export default function MusicList ({list}){ ...@@ -45,8 +52,9 @@ export default function MusicList ({list}){
</CardContent> </CardContent>
<CardActions> <CardActions>
<IconButton onClick={toggleFavorite(item.collectionCensoredName)}> <IconButton onClick={toggleFavorite(item.collectionId, item.collectionCensoredName, item)}>
{(likes[item.collectionCensoredName]===true)? <Favorite />:<FavoriteBorder />} {isLiked ?
<Favorite /> : <FavoriteBorder />}
</IconButton> </IconButton>
</CardActions> </CardActions>
</Card>) </Card>)
......
...@@ -2,18 +2,20 @@ import React from "react"; ...@@ -2,18 +2,20 @@ import React from "react";
import {Button, TextField} from "@mui/material"; import {Button, TextField} from "@mui/material";
import MusicList from "./MusicList"; import MusicList from "./MusicList";
export default function SearchPage ({list, onSearch}) { export default function SearchPage ({list, onSearch, likes, onLike}) {
const [searchWord, setSearchWord] = React.useState(""); const [searchWord, setSearchWord] = React.useState("");
const handleSearch = (event) => { const handleSearch = (event) => {
event.preventDefault(); event.preventDefault();
console.log(searchWord);
setSearchWord(""); fetch(`/musicSearch/${searchWord}`)
fetch(`http://itunes.apple.com/search?term=${searchWord}&entity=album`).then(r=>r.json()).then(r=>{ .then(response=>response.json())
.then(r=>{
console.log(r); console.log(r);
onSearch(r.results); onSearch(r.results);
setSearchWord(""); setSearchWord("");
}).catch(e=>console.log("error when search musician")); })
.catch(e=>console.log("error when search musician"));
} }
const handleSearchTextChange = (event)=>{ const handleSearchTextChange = (event)=>{
...@@ -32,9 +34,7 @@ export default function SearchPage ({list, onSearch}) { ...@@ -32,9 +34,7 @@ export default function SearchPage ({list, onSearch}) {
</Button> </Button>
</div> </div>
</form> </form>
<MusicList list={list} likes={likes} onLike={onLike}></MusicList>
{/* <MusicList list={music_list}></MusicList> */}
<MusicList list={list}></MusicList>
</React.Fragment> </React.Fragment>
) )
} }
...@@ -3,3 +3,4 @@ import ReactDOM from 'react-dom'; ...@@ -3,3 +3,4 @@ import ReactDOM from 'react-dom';
import App from './App'; import App from './App';
ReactDOM.render(<App/>, document.getElementById('app')); ReactDOM.render(<App/>, document.getElementById('app'));
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment