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

4

parent a5dca052
No related branches found
No related tags found
1 merge request!2Br
......@@ -7,7 +7,8 @@
"@emotion/react": "^11.9.3",
"@emotion/styled": "^11.9.3",
"@mui/icons-material": "^5.13.7",
"@mui/material": "^5.8.6"
"@mui/material": "^5.8.6",
"axios": "^1.4.0"
},
"devDependencies": {
"@babel/cli": "^7.18.6",
......
This diff is collapsed.
/*
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] = useState(0);
const [searchResult, setSearchResult] = useState([]);
const [likes, setLikes] = useState({});
const [favoriteList, setFavoriteList] = useState([]);
const handleTabChange = (event, newValue) => {
setCurrentTab(newValue);
};
const addToFavoriteList = (item) => {
setFavoriteList((prevList) => [...prevList, item]);
};
const handleLikes = (id) => {
setLikes((prevLikes) => ({ ...prevLikes, [id]: !prevLikes[id] }));
};
const removeFromFavoriteList = (id) => {
setFavoriteList((prevList) => prevList.filter((item) => item.collectionId !== id));
};
const TabComponent = TABS[currentTab].component;
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>
);
}
*/
import React, { useState } from 'react';
import SearchPage from './SearchPage';
import Favorites from './Favorites';
......
/*
import React, { useState } from 'react';
import { Card, CardContent, CardActions, IconButton, Typography } from '@mui/material';
import { Favorite, FavoriteBorder } from '@mui/icons-material';
......@@ -41,3 +42,52 @@ export default function Favorites({ favoriteList, likes, handleLikes, removeFrom
</div>
);
}
*/
import React, { useState, useEffect } from 'react';
import { Card, CardContent, CardActions, IconButton, Typography } from '@mui/material';
import { Favorite, FavoriteBorder } from '@mui/icons-material';
const styles = {
card: {
minWidth: 275,
maxWidth: 600,
marginBottom: '20pt',
marginLeft: 'auto',
marginRight: 'auto'
},
};
export default function Favorites({ favoriteList, likes, handleLikes, removeFromFavoriteList }) {
const [favoriteLikes, setFavoriteLikes] = useState(likes);
useEffect(() => {
setFavoriteLikes(likes);
}, [likes]);
const toggleFavorite = (id) => {
const updatedLikes = { ...favoriteLikes, [id]: !favoriteLikes[id] };
setFavoriteLikes(updatedLikes);
handleLikes(id);
};
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>
);
}
/*
import React from 'react';
import { Card, CardContent, CardActions, IconButton, Typography } from '@mui/material';
import { Favorite, FavoriteBorder } from '@mui/icons-material';
......@@ -59,3 +60,65 @@ export default function MusicList({ list, favoriteList, addToFavoriteList, likes
</div>
);
}
*/
import React from 'react';
import { Card, CardContent, CardActions, IconButton, Typography } from '@mui/material';
import { Favorite, FavoriteBorder } from '@mui/icons-material';
import SnackMsg from './Snackbar';
const styles = {
card: {
minWidth: 275,
maxWidth: 600,
marginBottom: '20pt',
marginLeft: 'auto',
marginRight: 'auto'
},
};
export default function MusicList({ list, favoriteList, addToFavoriteList, likes, handleLikes }) {
const [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 {
removeFromFavoriteList(id);
}
};
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.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>
);
}
/*
import React from 'react';
import { Button, TextField } from '@mui/material';
import MusicList from './MusicList';
......@@ -48,3 +49,58 @@ export default function SearchPage({ list, onSearch, favoriteList, addToFavorite
</React.Fragment>
);
}
*/
import React from 'react';
import { Button, TextField } from '@mui/material';
import MusicList from './MusicList';
const serverPort = 8098; // MySpringWeb Backend Server의 포트 번호
export default function SearchPage({ favoriteList, addToFavoriteList, likes, handleLikes }) {
const [searchWord, setSearchWord] = React.useState('');
const [searchResult, setSearchResult] = React.useState([]);
const handleSearch = (event) => {
event.preventDefault();
fetch(`http://localhost:${serverPort}/musicSearch/${searchWord}`)
.then((response) => response.json())
.then((data) => {
console.log(data);
setSearchResult(data.results);
setSearchWord('');
})
.catch((error) => console.error('음악 검색 중 오류가 발생했습니다.', error));
};
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="음악 앨범 검색"
type='search'
style={{ width: 450 }}
onChange={handleSearchTextChange}
value={searchWord}
/>
<Button variant="contained" color="primary" type="submit" onClick={handleSearch} style={{ marginLeft: 20 }}>
검색
</Button>
</div>
</form>
<MusicList
list={searchResult}
favoriteList={favoriteList}
addToFavoriteList={addToFavoriteList}
likes={likes}
handleLikes={handleLikes}
/>
</React.Fragment>
);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment