Skip to content

Commit

Permalink
Added loading in reducer and customstyled added
Browse files Browse the repository at this point in the history
  • Loading branch information
anasnadeemws committed Feb 29, 2024
1 parent 397371f commit 8f0871a
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 486 deletions.
82 changes: 60 additions & 22 deletions app/components/TrackCard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Card } from '@mui/material';
import styled from '@emotion/styled';
import T from '@components/T';
import If from '@components/If';
import isEmpty from 'lodash/isEmpty';
Expand All @@ -18,38 +19,75 @@ import Typography from '@mui/material/Typography';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import PauseIcon from '@mui/icons-material/Pause';

const TrackCustomCard = styled(Card)`
&& {
display: flex;
margin: 1rem;
width: 32rem;
justify-content: space-between;
:hover {
box-shadow: 5;
}
transition: all 0.25s linear;
}
`;

const TrackContentBox = styled(Box)`
&& {
display: flex;
flex-direction: column;
}
`;

const TrackMedia = styled(CardMedia)`
&& {
width: 10rem;
}
`;

const TrackContentHeaderBox = styled(TrackContentBox)`
&& {
flex-direction: row;
align-items: center;
padding-bottom: 1rem;
}
`;

const TrackPauseIcon = styled(PauseIcon)`
&& {
height: 2rem;
width: 2rem;
}
`;

const TrackPlayIcon = styled(PlayArrowIcon)`
&& {
height: 2rem;
width: 2rem;
}
`;

export function TrackCard({ collectionName, artistName, shortDescription, artworkUrl100, previewUrl }) {
const [playTrack, setPlayTrack] = useState(false);
const shortDesc =
shortDescription && shortDescription.length > 38 ? `${shortDescription.substring(0, 38)}...` : shortDescription;

return (
<Card
sx={{
display: 'flex',
margin: '1rem',
width: '32rem',
justifyContent: 'space-between',
':hover': {
boxShadow: 5
},
transition: 'all .25s linear'
}}
>
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
<CardContent sx={{ flex: '1 0 auto' }}>
<Box sx={{ display: 'flex', alignItems: 'center', pb: 1 }}>
<TrackCustomCard>
<TrackContentBox>
<CardContent>
<TrackContentHeaderBox>
<If condition={!isEmpty(previewUrl)}>
<IconButton aria-label="play/pause" onClick={() => setPlayTrack(!playTrack)}>
<If condition={playTrack} otherwise={<PlayArrowIcon sx={{ height: 32, width: 32 }} />}>
<PauseIcon sx={{ height: 32, width: 32 }} />
<If condition={playTrack} otherwise={<TrackPlayIcon />}>
<TrackPauseIcon />
</If>
</IconButton>
</If>
<Typography component="div" variant="h5">
{collectionName.length > 18 ? `${collectionName.substring(0, 18)}...` : collectionName}
{collectionName && collectionName.length > 18 ? `${collectionName.substring(0, 18)}...` : collectionName}
</Typography>
</Box>
</TrackContentHeaderBox>
<Typography variant="subtitle1" color="text.secondary" component="div">
<If
condition={!isEmpty(artistName)}
Expand All @@ -65,14 +103,14 @@ export function TrackCard({ collectionName, artistName, shortDescription, artwor
<T data-testid="track_shortdesc" id="track_shortdesc" values={{ desc: shortDesc }} />
</If>
</CardContent>
</Box>
<CardMedia component="img" sx={{ width: 151 }} image={artworkUrl100} alt={collectionName} />
</TrackContentBox>
<TrackMedia component="img" image={artworkUrl100} alt={collectionName} />
<If condition={playTrack}>
<audio autoPlay name="media">
<source src={previewUrl} />
</audio>
</If>
</Card>
</TrackCustomCard>
);
}

Expand Down
43 changes: 19 additions & 24 deletions app/containers/TrackContainer/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, memo, useState } from 'react';
import React, { useEffect, memo } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
Expand All @@ -16,11 +16,12 @@ import If from '@components/If';
import For from '@components/For';
import TrackCard from '@components/TrackCard';
import colors from '@app/themes/colors';
import { selectReposData, selectReposError, selectRepoName } from './selectors';
import { selectReposData, selectReposError, selectRepoName, selectRepoLoading } from './selectors';
import { trackContainerCreators } from './reducer';
import trackContainerSaga from './saga';
import { translate } from '@app/utils/index';

// Custom Styling
const CustomCard = styled(Card)`
&& {
margin: 1.25rem 0;
Expand Down Expand Up @@ -56,13 +57,11 @@ const RightContent = styled.div`
display: flex;
align-self: flex-end;
`;

const StyledT = styled(T)`
&& {
color: ${colors.gotoStories};
}
`;

const StyledOutlinedInput = styled(OutlinedInput)`
legend {
display: none;
Expand All @@ -79,37 +78,29 @@ export function TrackContainer({
tracksError,
trackName,
maxwidth,
padding
padding,
loading
}) {
const [loading, setLoading] = useState(false);
const history = useHistory();

useEffect(() => {
const loaded = get(tracksData, 'results', null) || tracksError;
if (loaded) {
setLoading(false);
}
}, [tracksData]);

useEffect(() => {
if (trackName && !tracksData?.results?.length) {
dispatchItunesTracks(trackName);
setLoading(true);
}
}, []);

const searchRepos = (rName) => {
dispatchItunesTracks(rName);
setLoading(true);
const searchTracks = (tName) => {
dispatchItunesTracks(tName);
};

const handleOnChange = (rName) => {
if (!isEmpty(rName)) {
searchRepos(rName);
const handleOnChange = (tName) => {
if (!isEmpty(tName)) {
searchTracks(tName);
} else {
dispatchClearItunesTracks();
}
};

const debouncedHandleOnChange = debounce(handleOnChange, 200);

const renderSkeleton = () => {
Expand Down Expand Up @@ -151,6 +142,7 @@ export function TrackContainer({
</If>
);
};

const renderErrorState = () => {
let trackError;
if (tracksError) {
Expand Down Expand Up @@ -197,7 +189,7 @@ export function TrackContainer({
data-testid="search-icon"
aria-label="search tracks"
type="button"
onClick={() => searchRepos(trackName)}
onClick={() => searchTracks(trackName)}
>
<SearchIcon />
</IconButton>
Expand All @@ -223,20 +215,23 @@ TrackContainer.propTypes = {
trackName: PropTypes.string,
history: PropTypes.object,
maxwidth: PropTypes.number,
padding: PropTypes.number
padding: PropTypes.number,
loading: PropTypes.boolean
};

TrackContainer.defaultProps = {
maxwidth: 500,
padding: 20,
tracksData: {},
tracksError: null
tracksError: null,
loading: false
};

const mapStateToProps = createStructuredSelector({
tracksData: selectReposData(),
tracksError: selectReposError(),
trackName: selectRepoName()
trackName: selectRepoName(),
loading: selectRepoLoading()
});

export function mapDispatchToProps(dispatch) {
Expand Down
6 changes: 5 additions & 1 deletion app/containers/TrackContainer/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,29 @@ export const { Types: trackContainerTypes, Creators: trackContainerCreators } =
failureGetItunesTracks: ['error'],
clearItunesTracks: {}
});
export const initialState = { trackName: null, tracksData: {}, tracksError: null };
export const initialState = { trackName: null, tracksData: {}, tracksError: null, loading: false };

/* eslint-disable default-case, no-param-reassign */
export const trackContainerReducer = (state = initialState, action) =>
produce(state, (draft) => {
switch (action.type) {
case trackContainerTypes.REQUEST_GET_ITUNES_TRACKS:
draft.trackName = action.trackName;
draft.loading = true;
break;
case trackContainerTypes.CLEAR_ITUNES_TRACKS:
draft.trackName = null;
draft.tracksError = null;
draft.tracksData = {};
draft.loading = false;
break;
case trackContainerTypes.SUCCESS_GET_ITUNES_TRACKS:
draft.tracksData = action.data;
draft.loading = false;
break;
case trackContainerTypes.FAILURE_GET_ITUNES_TRACKS:
draft.tracksError = get(action.error, 'message', 'something_went_wrong');
draft.loading = false;
break;
}
});
Expand Down
6 changes: 5 additions & 1 deletion app/containers/TrackContainer/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ export const selectReposData = () =>
export const selectReposError = () =>
createSelector(selecttrackContainerDomain, (substate) => get(substate, 'tracksError'));

export const selectRepoName = () => createSelector(selecttrackContainerDomain, (substate) => get(substate, 'trackName'));
export const selectRepoName = () =>
createSelector(selecttrackContainerDomain, (substate) => get(substate, 'trackName'));

export const selectRepoLoading = () =>
createSelector(selecttrackContainerDomain, (substate) => get(substate, 'loading'));
Loading

0 comments on commit 8f0871a

Please sign in to comment.