Skip to content

Commit

Permalink
Added equipment list (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
davewalker5 committed Dec 3, 2023
1 parent 6b31055 commit 8c60613
Show file tree
Hide file tree
Showing 9 changed files with 265 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/music-catalogue-ui/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const defaultContext = {
// Equipment registry
equipmentType: null,
manufacturer: null,
equipment: null,

// Data retrieval/filering criteria
filter: "A",
Expand All @@ -48,6 +49,7 @@ const App = () => {
genre = null,
equipmentType = null,
manufacturer = null,
equipment = null,
filter = "A",
isWishList = false,
} = {}) => {
Expand All @@ -61,6 +63,7 @@ const App = () => {
genre: typeof genre != "undefined" ? genre : null,
equipmentType: typeof equipmentType != "undefined" ? equipmentType : null,
manufacturer: typeof manufacturer != "undefined" ? manufacturer : null,
equipment: typeof equipment != "undefined" ? equipment : null,
filter: typeof filter != "undefined" ? filter : "A",
isWishList: typeof isWishList != "undefined" ? isWishList : false,
};
Expand Down
9 changes: 9 additions & 0 deletions src/music-catalogue-ui/components/componentPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import EquipmentTypeList from "./equipmentTypes/equipmentTypeList";
import EquipmentTypeEditor from "./equipmentTypes/equipmentTypeEditor";
import ManufacturerList from "./manufacturers/manufacturerList";
import ManufacturerEditor from "./manufacturers/manufacturerEditor";
import EquipmentList from "./equipment/equipmentList";

/**
* Component using the current context to select and render the current page
Expand Down Expand Up @@ -141,6 +142,14 @@ const ComponentPicker = ({ context, navigate, logout }) => {
logout={logout}
/>
);
case pages.equipment:
return (
<EquipmentList
isWishList={context.isWishList}
navigate={navigate}
logout={logout}
/>
);
case pages.export:
return <ExportCatalogue logout={logout} />;
case pages.artistStatisticsReport:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useCallback } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTrashAlt } from "@fortawesome/free-solid-svg-icons";
import {
apiDeleteEquipment,
apiFetchEquipment,
} from "@/helpers/api/apiEquipment";

/**
* Icon and associated action to delete an item of equipment
* @param {*} equipment
* @param {*} isWishList
* @param {*} logout
* @param {*} setEquipment
* @param {*} setError
* @returns
*/
const DeleteEquipmentActionIcon = ({
equipment,
isWishList,
logout,
setEquipment,
setError,
}) => {
/* Callback to prompt for confirmation and delete an item of equipment */
const confirmDeleteEquipment = useCallback(
async (e) => {
// Prevent the default action associated with the click event
e.preventDefault();

// Show a confirmation message and get the user response
const message = `This will delete the equipment "${equipment.description}" - click OK to confirm`;
const result = confirm(message);

// If they've confirmed the deletion ...
if (result) {
// ... delete the equipment and confirm the API call was successful
try {
const result = await apiDeleteEquipment(equipment.id, logout);
if (result) {
// Successful, so refresh the equipment list
const fetchedEquipment = await apiFetchEquipment(
isWishList,
logout
);
setEquipment(fetchedEquipment);
}
} catch (ex) {
setError(`Error deleting the equipment: ${ex.message}`);
}
}
},
[equipment, isWishList, logout, setEquipment, setError]
);

return (
<FontAwesomeIcon
icon={faTrashAlt}
onClick={(e) => confirmDeleteEquipment(e)}
/>
);
};

export default DeleteEquipmentActionIcon;
79 changes: 79 additions & 0 deletions src/music-catalogue-ui/components/equipment/equipmentList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import styles from "./equipmentList.module.css";
import pages from "@/helpers/navigation";
import useEquipment from "@/hooks/useEquipment";
import { useState } from "react";
import EquipmentRow from "./equipmentRow";

/**
* Component to render a table listing all the equipment in the register
* @param {*} isWishList
* @param {*} navigate
* @param {*} logout
* @returns
*/
const EquipmentList = ({ isWishList, navigate, logout }) => {
const { equipment, setEquipment } = useEquipment(logout);
const [error, setError] = useState("");

return (
<>
<div className="row mb-2 pageTitle">
<h5 className="themeFontColor text-center">Equipment</h5>
</div>
<div className="row">
{error != "" ? (
<div className={styles.equipmentListError}>{error}</div>
) : (
<></>
)}
</div>
<table className="table table-hover">
<thead>
<tr>
<th>Description</th>
<th>Model</th>
<th>Serial No.</th>
<th>Type</th>
<th>Manufacturer</th>
<th>Purchased</th>
<th>Price</th>
<th>Retailer</th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
{equipment != null && (
<tbody>
{equipment.map((e) => (
<EquipmentRow
key={e.id}
equipment={e}
isWishList={isWishList}
navigate={navigate}
logout={logout}
setEquipment={setEquipment}
setError={setError}
/>
))}
</tbody>
)}
</table>
<div className={styles.equipmentListAddButton}>
<button
className="btn btn-primary"
onClick={() =>
navigate({
page: pages.equipmentEditor,
})
}
>
Add
</button>
</div>
</>
);
};

export default EquipmentList;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.equipmentListAddButton {
float: right;
}

.equipmentListError {
font-weight: bold;
color: red;
text-align: center;
}
96 changes: 96 additions & 0 deletions src/music-catalogue-ui/components/equipment/equipmentRow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import pages from "@/helpers/navigation";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPenToSquare } from "@fortawesome/free-solid-svg-icons";
import DeleteEquipmentActionIcon from "./deleteEquipmentActionIcon";
import DateFormatter from "../common/dateFormatter";
import CurrencyFormatter from "../common/currencyFormatter";

/**
* Component to render a row containing the details for a single item of equipment
* @param {*} equipment
* @param {*} isWishList
* @param {*} navigate
* @param {*} logout
* @param {*} setManufacturers
* @param {*} setError
* @returns
*/
const EquipmentRow = ({
equipment,
isWishList,
navigate,
logout,
setEquipment,
setError,
}) => {
// Get the equipment type name
const equipmentType = equipment["equipmentType"];
const equipmentTypeName = equipmentType != null ? equipmentType["name"] : "";

// Get the manufacturer name
const manufacturer = equipment["manufacturer"];
const manufacturerName = manufacturer != null ? manufacturer["name"] : "";

// Get the retailer name
const retailer = equipment["retailer"];
const retailerName = retailer != null ? retailer["name"] : "";

return (
<tr>
<td>{equipment.description}</td>
<td>{equipment.model}</td>
<td>{equipment.serialNumber}</td>
<td>{equipmentTypeName}</td>
<td>{manufacturerName}</td>
<td>
<DateFormatter value={equipment.purchased} />
</td>
<td>
<CurrencyFormatter value={equipment.price} renderZeroAsBlank={true} />
</td>
<td>{retailerName}</td>
<td>
<DeleteEquipmentActionIcon
equipment={equipment}
isWishList={isWishList}
logout={logout}
setEquipment={setEquipment}
setError={setError}
/>
</td>
<td>
<FontAwesomeIcon
icon={faPenToSquare}
onClick={() =>
navigate({
page: pages.equipmentEditor,
equipment: equipment,
})
}
/>
</td>
<td>
{/* <AlbumWishListActionIcon
album={album}
isWishList={isWishList}
logout={logout}
setAlbums={setAlbums}
/> */}
</td>
<td>
{/* <FontAwesomeIcon
icon={faCoins}
onClick={() =>
navigate({
page: pages.albumPurchaseDetails,
artist: artist,
album: album,
})
}
/> */}
</td>
</tr>
);
};

export default EquipmentRow;
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const DeleteManufacturerActionIcon = ({
setManufacturers,
setError,
}) => {
/* Callback to prompt for confirmation and delete amanufacturer */
/* Callback to prompt for confirmation and delete avmanufacturer */
const confirmDeleteManufacturer = useCallback(
async (e) => {
// Prevent the default action associated with the click event
Expand All @@ -41,7 +41,7 @@ const DeleteManufacturerActionIcon = ({
setManufacturers(fetchedManufacturers);
}
} catch (ex) {
setError(`Error deleting the equipment type: ${ex.message}`);
setError(`Error deleting the manufacturer: ${ex.message}`);
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/music-catalogue-ui/components/menuBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const MenuBar = ({ navigate, logout }) => {
</div>
</button>
<div className={styles.dropdownContent}>
<a>Equipment</a>
<a onClick={() => navigate({ page: pages.equipment })}>Equipment</a>
<a>Wish List</a>
<a onClick={() => navigate({ page: pages.equipmentTypes })}>
Equipment Types
Expand Down
2 changes: 2 additions & 0 deletions src/music-catalogue-ui/helpers/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const pages = {
equipmentTypeEditor: "EquipmentTypeEditor",
manufacturers: "Manufacturers",
manufacturerEditor: "ManufacturerEditor",
equipment: "Equipment",
equipmentEditor: "EquipmentEditor",
lookup: "Lookup",
export: "Export",
artistStatisticsReport: "ArtistStatisticsReport",
Expand Down

0 comments on commit 8c60613

Please sign in to comment.