-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: develop card for songs and store api data in redux
- Loading branch information
Wednesday Solutions
authored and
Wednesday Solutions
committed
Oct 4, 2024
1 parent
c02a957
commit 778aa5e
Showing
6 changed files
with
289 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import React from 'react'; | ||
import styled from '@emotion/styled'; | ||
import { string } from 'prop-types'; | ||
import { If } from '../If/index'; | ||
|
||
const Card = styled.div` | ||
border-style: solid; | ||
border-width: 1px; | ||
padding: 5px; | ||
border-radius: 5px; | ||
&:hover { | ||
cursor: pointer; | ||
background: #eaeaea; | ||
} | ||
&:active { | ||
background: #cacaca; | ||
} | ||
`; | ||
|
||
/** | ||
* MediaItemCard component that displays information about a Media item (like a song). | ||
* It shows the repository's name, full name, and star count. | ||
* | ||
* @date 01/03/2024 - 14:47:28 | ||
* | ||
* @param {Object} props - The component props. | ||
* @param {string} props.trackName - The name of the track. | ||
* @param {string} props.collectionName - The name of the collection. | ||
* @param {string} props.artistName - The name of the artist. | ||
* @param {string} props.country - The name of the country the media is from | ||
* @param {string} props.primaryGenreName - Genre name | ||
* @param {string} props.thumbnailSrc - thumbnail of the media | ||
* @returns {JSX.Element} The RepoCard component displaying the repository information. | ||
*/ | ||
export function MediaItemCard({ trackName, collectionName, artistName, country, primaryGenreName, thumbnailSrc }) { | ||
return ( | ||
<Card> | ||
<If condition={thumbnailSrc}> | ||
<img src={thumbnailSrc} alt="thumbnail" /> | ||
</If> | ||
<If condition={trackName}> | ||
<div>{trackName}</div> | ||
</If> | ||
<If condition={collectionName}> | ||
<div>{collectionName}</div> | ||
</If> | ||
<If condition={artistName}> | ||
<div>{artistName}</div> | ||
</If> | ||
<If condition={country}> | ||
<div>{country}</div> | ||
</If> | ||
<If condition={primaryGenreName}> | ||
<div>{primaryGenreName}</div> | ||
</If> | ||
</Card> | ||
); | ||
} | ||
|
||
MediaItemCard.propTypes = { | ||
trackName: string, | ||
collectionName: string, | ||
artistName: string, | ||
country: string, | ||
primaryGenreName: string, | ||
thumbnailSrc: string | ||
}; | ||
|
||
export default MediaItemCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* | ||
* HomeContainer reducer | ||
* | ||
*/ | ||
import { produce } from 'immer'; | ||
import { createActions } from 'reduxsauce'; | ||
import get from 'lodash/get'; | ||
|
||
export const { Types: songsContainerTypes, Creators: songsContainerCreators } = createActions({ | ||
requestGetItuneSongs: ['songName'], | ||
successGetItuneSongs: ['data'], | ||
failureGetItuneSongs: ['error'], | ||
clearItuneSongs: {} | ||
}); | ||
export const initialState = { songName: null, songsData: {}, songsError: null, loading: null }; | ||
|
||
export const songsContainerReducer = (state = initialState, action) => | ||
produce(state, (draft) => { | ||
switch (action.type) { | ||
case songsContainerTypes.REQUEST_GET_ITUNE_SONGS: | ||
draft.songName = action.songName; | ||
draft.loading = true; | ||
break; | ||
case songsContainerTypes.CLEAR_ITUNE_SONGS: | ||
draft.songName = null; | ||
draft.songsError = null; | ||
draft.songsData = {}; | ||
draft.loading = null; | ||
break; | ||
case songsContainerTypes.SUCCESS_GET_ITUNE_SONGS: | ||
draft.songsData = action.data; | ||
draft.songsError = null; | ||
draft.loading = false; | ||
break; | ||
case songsContainerTypes.FAILURE_GET_ITUNE_SONGS: | ||
draft.songsError = get(action.error, 'message', 'something_went_wrong'); | ||
draft.songsData = null; | ||
draft.loading = false; | ||
break; | ||
} | ||
}); | ||
|
||
export default songsContainerReducer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { put, call, takeLatest } from 'redux-saga/effects'; | ||
import { songsContainerCreators, songsContainerTypes } from './reducer'; | ||
import { getSongs } from '@services/songApi'; | ||
|
||
const { REQUEST_GET_ITUNE_SONGS } = songsContainerTypes; | ||
const { successGetItuneSongs, failureGetItuneSongs } = songsContainerCreators; | ||
|
||
/** | ||
* A saga that handles fetching GitHub repositories based on a given repository name. | ||
* On success, it dispatches a success action with the fetched data. | ||
* On failure, it dispatches a failure action with the error data. | ||
* | ||
* @date 01/03/2024 - 14:47:28 | ||
* | ||
* @param {Object} action - The action object containing the repository name. | ||
* @yields {Effect} The effect of calling the API, and then either the success or failure action. | ||
*/ | ||
export function* getItuneSongs(action) { | ||
const response = yield call(getSongs, action.songName); | ||
const { data, ok } = response; | ||
if (ok) { | ||
yield put(successGetItuneSongs(data)); | ||
} else { | ||
yield put(failureGetItuneSongs(data)); | ||
} | ||
} | ||
|
||
/** | ||
* registering events | ||
* @date 04/03/2024 - 12:57:49 | ||
* | ||
* @export | ||
* @returns {{}} | ||
*/ | ||
export default function* songsContainerSaga() { | ||
yield takeLatest(REQUEST_GET_ITUNE_SONGS, getItuneSongs); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { createSelector } from 'reselect'; | ||
import get from 'lodash/get'; | ||
import { initialState } from './reducer'; | ||
|
||
/** | ||
* Direct selector to the homeContainer state domain | ||
*/ | ||
|
||
export const selectSongsContainerDomain = (state) => state.songsContainer || initialState; | ||
|
||
/** | ||
* Other specific selectors | ||
*/ | ||
|
||
/** | ||
* Default selector used by HomeContainer | ||
*/ | ||
|
||
export const selectSongsData = () => | ||
createSelector(selectSongsContainerDomain, (substate) => get(substate, 'songsData')); | ||
|
||
export const selectLoading = () => createSelector(selectSongsContainerDomain, (substate) => get(substate, 'loading')); | ||
|
||
export const selectSongsError = () => | ||
createSelector(selectSongsContainerDomain, (substate) => get(substate, 'songsError')); | ||
|
||
export const selectSongName = () => createSelector(selectSongsContainerDomain, (substate) => get(substate, 'songName')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters