Skip to content

Commit

Permalink
Add song details page (#13)
Browse files Browse the repository at this point in the history
* Rename webpack cfgs

* Fix middlewares deprecation warning

* Fully remove warnings for npm start

* Relax browserslist constraints

* Enable routes and add bogus song details

* Turn titles into hrefs

* Rethink components file structure

* Provide scaffolded fetch logic for release details
  • Loading branch information
kostmetallist authored Feb 13, 2024
1 parent 2cc4875 commit 2ea5536
Show file tree
Hide file tree
Showing 16 changed files with 143 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,27 +101,22 @@ module.exports = function (proxy, allowedHost) {
},
// `proxy` is run between `before` and `after` `webpack-dev-server` hooks
proxy,
onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));
setupMiddlewares: (middlewares, devServer) => {
if (!devServer) {
throw new Error('webpack-dev-server is not defined');
}

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},
onAfterSetupMiddleware(devServer) {
// Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match
devServer.app.use(redirectServedPath(paths.publicUrlOrPath));

// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// We do this in development to avoid hitting the production cache if
// it used the same host and port.
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
devServer.app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath));
middlewares.push(
evalSourceMapMiddleware(devServer),
redirectServedPath(paths.publicUrlOrPath),
noopServiceWorkerMiddleware(paths.publicUrlOrPath)
);

return middlewares;
},
};
};
45 changes: 26 additions & 19 deletions vanguarde/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 5 additions & 19 deletions vanguarde/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "taburette-vanguarde",
"version": "0.1.2",
"version": "0.2.1",
"private": true,
"dependencies": {
"@babel/core": "^7.16.0",
Expand All @@ -14,7 +14,7 @@
"babel-plugin-named-asset-import": "^0.3.8",
"babel-preset-react-app": "^10.0.1",
"bfj": "^7.0.2",
"browserslist": "^4.18.1",
"browserslist": "^4.22.3",
"camelcase": "^6.2.1",
"case-sensitive-paths-webpack-plugin": "^2.4.0",
"css-loader": "^6.5.1",
Expand Down Expand Up @@ -81,23 +81,9 @@
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"test": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"browserslist": [
"defaults"
],
"babel": {
"presets": [
"react-app"
Expand Down
2 changes: 1 addition & 1 deletion vanguarde/scripts/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const openBrowser = require('react-dev-utils/openBrowser');
const semver = require('semver');
const paths = require('../config/paths');
const configFactory = require('../config/webpack.config');
const createDevServerConfig = require('../config/webpackDevServer.config');
const createDevServerConfig = require('../config/webpack.config.dev');
const getClientEnvironment = require('../config/env');
const react = require(require.resolve('react', { paths: [paths.appPath] }));

Expand Down
18 changes: 11 additions & 7 deletions vanguarde/src/App.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';

import MainPage from './components/MainPage';
import { JokerFooter } from './components/JokerFooter';
import { Header } from './components/Header';
import { MainPage } from './components/main/MainPage';
import { SongDetails } from './components/track/SongDetails';
import { Header } from './components/shared/Header';
import { JokerFooter } from './components/shared/JokerFooter';

function App() {
return (
<Router>
<Header/>
<MainPage/>
<JokerFooter/>
<Header />
<Routes>
<Route exact path='/' element={ <MainPage /> }/>
<Route path='/s/:songId' element={ <SongDetails /> }/>
</Routes>
<JokerFooter />
</Router>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@ import { MDBCol, MDBContainer, MDBRow } from 'mdb-react-ui-kit';

import SongList from './SongList.jsx';

class MainPage extends Component {
export class MainPage extends Component {
render() {
return (
<MDBContainer className='mt-5' fluid>
<MDBRow>
<MDBCol md="2" />
<MDBCol md="8">
<SongList/>
<SongList />
</MDBCol>
<MDBCol md="2" />
</MDBRow>
</MDBContainer>
);
}
}

export default MainPage;
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Select from 'react-select';

import { changeSearchQuery } from '../redux/search';
import { ARTIST_QUERY, RELEASE_QUERY, SONG_QUERY, GENRE_QUERY } from '../redux/search';
import { changeSearchQuery } from '../../redux/search';
import { ARTIST_QUERY, RELEASE_QUERY, SONG_QUERY, GENRE_QUERY } from '../../redux/search';

const genreOptions = [
{ value: 'rock', label: 'Rock' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import {
import React, { Component } from 'react';
import PropTypes from 'prop-types';

import placeholder from '../assets/150.png';
import '../index.css';
import placeholder from '../../assets/150.png';
import '../../index.css';

export class SongCard extends Component {
static propTypes = {
artist: PropTypes.string.isRequired,
trackId: PropTypes.number.isRequired,
trackName: PropTypes.string.isRequired,
};

Expand All @@ -25,7 +26,9 @@ export class SongCard extends Component {
<div className="col-md-6">
<div className="card-body">
<h4 className="card-title">
{this.props.trackName}
<a href={`/s/${this.props.trackId}`}>
{this.props.trackName}
</a>
</h4>
<h6 className="card-subtitle">
by {this.props.artist}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {
import { connect } from 'react-redux';

import SearchOptions from './SearchOptions';
import { toggleSearchBar, handleOmnibarChange, handleSortToggle } from '../redux/search';
import { getSongList } from '../redux/songs';
import { toggleSearchBar, handleOmnibarChange, handleSortToggle } from '../../redux/search.js';
import { getSongList } from '../../redux/songs.js';

class SongList extends Component {
static propTypes = {
Expand Down Expand Up @@ -77,10 +77,10 @@ class SongList extends Component {
<MDBRow className='mt-3' data-cy='song-list'>
{
this.props.songList.map((value, index) => {
const trackName = value.name;
const featuredArtists = value.release.artists.map(
(artist) => artist.name).join(';');
return <SongCard key={index} artist={featuredArtists} trackName={trackName} />;
const featuredArtists = value.release.artists
.map((artist) => artist.name)
.join(';');
return <SongCard key={index} artist={featuredArtists} trackName={value.name} trackId={value.id} />;
})
}
</MDBRow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class Header extends Component {
return (
<MDBNavbar bgColor='dark' color="elegant-color" dark expand='xl'>
<MDBContainer>
<MDBNavbarBrand href='#!'>
<MDBNavbarBrand href='/'>
<strong className="white-text">Taburette</strong>
</MDBNavbarBrand>
{/* TODO: Enable toggler after class -> function components rearch */}
Expand All @@ -24,7 +24,7 @@ export class Header extends Component {
<MDBCollapse navbar>
<MDBNavbarNav>
<MDBNavbarItem>
<MDBNavbarLink active aria-current='home' href="#!">Home</MDBNavbarLink>
<MDBNavbarLink active aria-current='home' href="/">Home</MDBNavbarLink>
</MDBNavbarItem>
<MDBNavbarItem>
<MDBNavbarLink disabled aria-disabled='true' href="#!">About</MDBNavbarLink>
Expand Down
File renamed without changes.
20 changes: 20 additions & 0 deletions vanguarde/src/components/track/SongDetails.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { useParams } from 'react-router-dom';
import { MDBCol, MDBContainer, MDBRow } from 'mdb-react-ui-kit';

export function SongDetails() {

let { songId } = useParams();

return (
<MDBContainer className='mt-5' fluid>
<MDBRow>
<MDBCol md="2" />
<MDBCol md="8">
Here lieth song details for release {songId}.
</MDBCol>
<MDBCol md="2" />
</MDBRow>
</MDBContainer>
);
}
1 change: 1 addition & 0 deletions vanguarde/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const rootReducer = {
searchReducer: searchReducer,
songReducer: songReducer,
};

const store = configureStore({
reducer: rootReducer,
middleware: getDefaultMiddleware({
Expand Down
4 changes: 2 additions & 2 deletions vanguarde/src/redux/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export function handleError(errorObj) {
onScreen: true,
},
type: 'danger',
insert: 'top',
container: 'top-right',
insert: 'bottom',
container: 'bottom-right',
animationIn: ['animated', 'fadeIn'],
animationOut: ['animated', 'fadeOut'],
});
Expand Down
45 changes: 45 additions & 0 deletions vanguarde/src/redux/release.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { createSlice } from '@reduxjs/toolkit';
import axios from 'axios';

const initialState = {
releaseDetails: {},
loading: false,
error: null,
};

const releaseSlice = createSlice({
name: 'release',
initialState,
reducers: {
fetchBegin: (state, action) => {
state.loading = true;
state.error = null;
},
fetchSuccess: (state, action) => {
state.loading = false;
state.releaseDetails = action.payload;
},
fetchError: (state, action) => {
state.loading = false;
state.error = action.payload.error;
},
},
});

const { actions, reducer } = releaseSlice;
const { fetchBegin, fetchSuccess, fetchError } = actions;

export function getReleaseDetails(dispatch, getState, {apiConfig}) {
dispatch(fetchBegin());

// TODO: remove hardcoded release id
axios.get(`${apiConfig.url}/releases/12829`)
.then((res) => {
dispatch(fetchSuccess(res.data));
})
.catch((error) => {
dispatch(fetchError(error));
});
}

export default reducer;
Loading

0 comments on commit 2ea5536

Please sign in to comment.