Skip to content

Commit

Permalink
Added a track editing component
Browse files Browse the repository at this point in the history
  • Loading branch information
davewalker5 committed Nov 24, 2023
1 parent bccb965 commit 2dae22a
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 21 deletions.
5 changes: 4 additions & 1 deletion src/music-catalogue-ui/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ const defaultContext = {
// Current page
page: pages.artists,

// Artist, album and retailer context
// Artist, album, track and retailer context
artist: null,
album: null,
track: null,
retailer: null,

// Data retrieval/filering criteria
Expand All @@ -38,6 +39,7 @@ const App = () => {
page = pages.artists,
artist = null,
album = null,
track = null,
retailer = null,
genre = null,
filter = "A",
Expand All @@ -48,6 +50,7 @@ const App = () => {
page: page,
artist: typeof artist != "undefined" ? artist : null,
album: typeof album != "undefined" ? album : null,
track: typeof track != "undefined" ? track : null,
retailer: typeof retailer != "undefined" ? retailer : null,
genre: typeof genre != "undefined" ? genre : null,
filter: typeof filter != "undefined" ? filter : "A",
Expand Down
43 changes: 27 additions & 16 deletions src/music-catalogue-ui/components/componentPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import GenreList from "./genreList";
import RetailerList from "./retailerList";
import RetailerDetails from "./retailerDetails";
import RetailerEditor from "./retailerEditor";
import TrackEditor from "./trackEditor";

/**
* Component using the current context to select and render the current page
Expand All @@ -33,8 +34,6 @@ const ComponentPicker = ({ context, navigate, logout }) => {
logout={logout}
/>
);
case pages.genres:
return <GenreList navigate={navigate} logout={logout} />;
case pages.albums:
return (
<AlbumList
Expand All @@ -44,6 +43,15 @@ const ComponentPicker = ({ context, navigate, logout }) => {
logout={logout}
/>
);
case pages.albumPurchaseDetails:
return (
<AlbumPurchaseDetails
artist={context.artist}
album={context.album}
navigate={navigate}
logout={logout}
/>
);
case pages.tracks:
return (
<TrackList
Expand All @@ -54,27 +62,18 @@ const ComponentPicker = ({ context, navigate, logout }) => {
logout={logout}
/>
);
case pages.lookup:
return <LookupAlbum navigate={navigate} logout={logout} />;
case pages.export:
return <ExportCatalogue logout={logout} />;
case pages.artistStatisticsReport:
return <ArtistStatisticsReport logout={logout} />;
case pages.genreStatisticsReport:
return <GenreStatusReport logout={logout} />;
case pages.jobStatusReport:
return <JobStatusReport logout={logout} />;
case pages.monthlySpendReport:
return <MonthlySpendReport logout={logout} />;
case pages.albumPurchaseDetails:
case pages.trackEditor:
return (
<AlbumPurchaseDetails
<TrackEditor
track={context.track}
artist={context.artist}
album={context.album}
navigate={navigate}
logout={logout}
/>
);
case pages.lookup:
return <LookupAlbum navigate={navigate} logout={logout} />;
case pages.retailers:
return <RetailerList navigate={navigate} logout={logout} />;
case pages.retailerDetails:
Expand All @@ -93,6 +92,18 @@ const ComponentPicker = ({ context, navigate, logout }) => {
logout={logout}
/>
);
case pages.genres:
return <GenreList navigate={navigate} logout={logout} />;
case pages.export:
return <ExportCatalogue logout={logout} />;
case pages.artistStatisticsReport:
return <ArtistStatisticsReport logout={logout} />;
case pages.genreStatisticsReport:
return <GenreStatusReport logout={logout} />;
case pages.jobStatusReport:
return <JobStatusReport logout={logout} />;
case pages.monthlySpendReport:
return <MonthlySpendReport logout={logout} />;
default:
return <span />;
}
Expand Down
165 changes: 165 additions & 0 deletions src/music-catalogue-ui/components/trackEditor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import styles from "./trackEditor.module.css";
import pages from "@/helpers/navigation";
import FormInputField from "./formInputField";
import { useState, useCallback } from "react";
import { apiCreateTrack, apiUpdateTrack } from "@/helpers/apiTracks";

const TrackEditor = ({ track, album, artist, navigate, logout }) => {
// Split the track's formatted duration on the ":"
let initialMinutes = null;
let initialSeconds = null;
if (track.formattedDuration != null) {
const elements = track.formattedDuration.split(":");
if (elements.length > 0) {
initialMinutes = elements[0];
initialSeconds = elements[1];
}
}

const [title, setTitle] = useState(track.title);
const [number, setNumber] = useState(track.number);
const [minutes, setMinutes] = useState(initialMinutes);
const [seconds, setSeconds] = useState(initialSeconds);
const [error, setError] = useState("");

/* Callback to save retailer details */
const saveTrack = useCallback(
async (e) => {
// Prevent the default action associated with the click event
e.preventDefault();

// Clear pre-existing errors
setError("");

try {
// Calculate the duration from the indiviidual minutes and seconds
// inputs
const durationMinutes = Number(minutes);
const durationSeconds = Number(seconds);
const duration = 1000 * (60 * durationMinutes + durationSeconds);

// Either add or update the track, depending on whether they currently
// have an ID
let updatedTrack = null;
if (track.id <= 0) {
// Invalid ID, so create a new track
updatedTrack = await apiCreateTrack(
title,
number,
duration,
album.id,
logout
);
} else {
// Has a valid ID, so update an existing track
updatedTrack = await apiUpdateTrack(
track.id,
title,
number,
duration,
album.id,
logout
);
}

// If all's well, navigate back to the track list page. Otherwise, show an error
if (updatedTrack == null) {
const action = track.Id <= 0 ? "adding" : "updating";
setError(`An error occurred ${action} the track`);
} else {
navigate({
page: pages.tracks,
artist: artist,
album: album,
});
}
} catch (e) {
setError(
e.message
//"Error converting the supplied minutes and seconds to a duration"
);
}
},
[album, artist, track, title, number, minutes, seconds, navigate, logout]
);

return (
<>
<div className="row mb-2 pageTitle">
<h5 className="themeFontColor text-center">{title}</h5>
</div>
<div className={styles.trackEditorFormContainer}>
<form className={styles.trackEditorForm}>
<div className="row">
{error != "" ? (
<div className={styles.trackEditorError}>{error}</div>
) : (
<></>
)}
</div>
<div className="row align-items-start">
<div className="col">
<FormInputField
label="Title"
name="title"
value={title}
setValue={setTitle}
/>
</div>
</div>
<div className="row align-items-start">
<div className="col">
<FormInputField
label="Number"
name="number"
value={number}
setValue={setNumber}
/>
</div>
</div>
<div className="row align-items-start">
<div className="col">
<FormInputField
label="Minutes"
name="minutes"
value={minutes}
setValue={setMinutes}
/>
</div>
<div className="col">
<FormInputField
label="Seconds"
name="seconds"
value={seconds}
setValue={setSeconds}
/>
</div>
</div>
<div className="d-grid gap-2 mt-3"></div>
<div className="d-grid gap-2 mt-3"></div>
<div className={styles.trackEditorButton}>
<button className="btn btn-primary" onClick={(e) => saveTrack(e)}>
Save
</button>
</div>
<div className={styles.trackEditorButton}>
<button
className="btn btn-primary"
onClick={() =>
navigate({
page: pages.tracks,
artist: artist,
album: album,
})
}
>
Cancel
</button>
</div>
</form>
</div>
</>
);
};

export default TrackEditor;
25 changes: 25 additions & 0 deletions src/music-catalogue-ui/components/trackEditor.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.trackEditorFormContainer {
display: flex;
justify-content: center;
align-items: center;
}

.trackEditorForm {
width: 80%;
padding-top: 20px;
padding-bottom: 20px;
}

.trackEditorButton {
margin-left: 10px;
float: right;
}

.trackEditorError {
font-weight: bold;
color: red;
}

.trackEditorGeocode {
margin-left: 10px;
}
15 changes: 15 additions & 0 deletions src/music-catalogue-ui/components/trackRow.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import DeleteTrackActionIcon from "./deleteTrackActionIcon";
import styles from "./trackRow.module.css";
import pages from "@/helpers/navigation";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPenToSquare } from "@fortawesome/free-solid-svg-icons";

/**
* Component to render a row containing the details for a single track
Expand Down Expand Up @@ -41,6 +43,19 @@ const TrackRow = ({
setTracks={setTracks}
/>
</td>
<td>
<FontAwesomeIcon
icon={faPenToSquare}
onClick={() =>
navigate({
page: pages.trackEditor,
artist: artist,
album: album,
track: track,
})
}
/>
</td>
</tr>
);
};
Expand Down
9 changes: 5 additions & 4 deletions src/music-catalogue-ui/helpers/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ const pages = {
genres: "Genres",
wishlistArtists: "WishlistArtists",
albums: "Albums",
wishlistAlbums: "wishlistAlbums",
wishlistAlbums: "WishlistAlbums",
tracks: "Tracks",
trackEditor: "TrackEditor",
retailers: "Retailers",
retailerDetails: "RetailerDetails",
retailerEditor: "RetailerEditor",
lookup: "Lookup",
export: "Export",
artistStatisticsReport: "ArtistStatisticsReport",
genreStatisticsReport: "GenreStatisticsReport",
jobStatusReport: "JobStatusReport",
monthlySpendReport: "MonthlySpendReport",
albumPurchaseDetails: "AlbumPurchaseDetails",
retailers: "Retailers",
retailerDetails: "RetailerDetails",
retailerEditor: "RetailerEditor",
};

export default pages;

0 comments on commit 2dae22a

Please sign in to comment.