-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement equipment list and editing options
- Loading branch information
1 parent
8c60613
commit f458800
Showing
13 changed files
with
424 additions
and
16 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
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
Empty file.
27 changes: 27 additions & 0 deletions
27
src/music-catalogue-ui/components/equipment/equipmentEditor.module.css
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 @@ | ||
.equipmentEditorFormContainer { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
} | ||
|
||
.equipmentEditorForm { | ||
width: 80%; | ||
padding-top: 20px; | ||
padding-bottom: 20px; | ||
} | ||
|
||
.equipmentEditorFormLabel { | ||
font-size: 14px; | ||
font-weight: 600; | ||
color: rgb(34, 34, 34); | ||
} | ||
|
||
.equipmentEditorButton { | ||
margin-left: 10px; | ||
float: right; | ||
} | ||
|
||
.equipmentEditorError { | ||
font-weight: bold; | ||
color: red; | ||
} |
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
27 changes: 27 additions & 0 deletions
27
src/music-catalogue-ui/components/equipment/equipmentPurchaseDetails.module.css
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 @@ | ||
.purchaseDetailsFormContainer { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
} | ||
|
||
.purchaseDetailsForm { | ||
width: 420px; | ||
padding-top: 20px; | ||
padding-bottom: 20px; | ||
} | ||
|
||
.purchaseDetailsFormLabel { | ||
font-size: 14px; | ||
font-weight: 600; | ||
color: rgb(34, 34, 34); | ||
} | ||
|
||
.purchaseDetailsButton { | ||
margin-left: 10px; | ||
float: right; | ||
} | ||
|
||
.purchaseDetailsError { | ||
font-weight: bold; | ||
color: red; | ||
} |
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
48 changes: 48 additions & 0 deletions
48
src/music-catalogue-ui/components/equipment/equipmentWishListActionIcon.js
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,48 @@ | ||
import { useCallback } from "react"; | ||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||
import { | ||
faHeartCirclePlus, | ||
faRecordVinyl, | ||
} from "@fortawesome/free-solid-svg-icons"; | ||
import { | ||
apiFetchEquipment, | ||
apiSetEquipmentWishListFlag, | ||
} from "@/helpers/api/apiEquipment"; | ||
|
||
/** | ||
* Icon and associated action to move an item of equipment between the main | ||
* registry and wish list | ||
* @param {*} equipment | ||
* @param {*} isWishList | ||
* @param {*} logout | ||
* @param {*} setEquipment | ||
* @returns | ||
*/ | ||
const EquipmentWishListActionIcon = ({ | ||
equipment, | ||
isWishList, | ||
logout, | ||
setEquipment, | ||
}) => { | ||
// Set the icon depending on the direction in which the equipment will move | ||
const icon = isWishList ? faRecordVinyl : faHeartCirclePlus; | ||
|
||
/* Callback to move an album between the wish list and catalogue */ | ||
const setEquipmentWishListFlag = useCallback(async () => { | ||
// Move the album to the wish list | ||
const result = await apiSetEquipmentWishListFlag( | ||
equipment, | ||
!isWishList, | ||
logout | ||
); | ||
if (result) { | ||
// Successful, so refresh the album list | ||
const fetchedEquipment = await apiFetchEquipment(isWishList, logout); | ||
setEquipment(fetchedEquipment); | ||
} | ||
}, [equipment, isWishList, logout, setEquipment]); | ||
|
||
return <FontAwesomeIcon icon={icon} onClick={setEquipmentWishListFlag} />; | ||
}; | ||
|
||
export default EquipmentWishListActionIcon; |
161 changes: 161 additions & 0 deletions
161
src/music-catalogue-ui/components/equipment/equpimentPurchaseDetails.js
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,161 @@ | ||
import styles from "./equipmentPurchaseDetails.module.css"; | ||
import DatePicker from "react-datepicker"; | ||
import { useState, useCallback } from "react"; | ||
import CurrencyInput from "react-currency-input-field"; | ||
import config from "@/config.json"; | ||
import pages from "@/helpers/navigation"; | ||
import RetailerSelector from "../retailers/retailerSelector"; | ||
import { apiSetEquipmentPurchaseDetails } from "@/helpers/api/apiEquipment"; | ||
|
||
/** | ||
* Form to set the equipment purchase details for an item of equipment | ||
* @param {*} equipment | ||
* @param {*} navigate | ||
* @param {*} logout | ||
*/ | ||
const EquipmentPurchaseDetails = ({ equipment, navigate, logout }) => { | ||
// Get the initial retailer selection and purchase date | ||
let initialRetailer = null; | ||
let initialPurchaseDate = new Date(); | ||
if (equipment != null) { | ||
initialRetailer = equipment.retailer; | ||
|
||
if (equipment.purchased != null) { | ||
initialPurchaseDate = new Date(equipment.purchased); | ||
} | ||
} | ||
|
||
// Set up state | ||
const [purchaseDate, setPurchaseDate] = useState(initialPurchaseDate); | ||
const [price, setPrice] = useState(equipment.price); | ||
const [retailer, setRetailer] = useState(initialRetailer); | ||
const [errorMessage, setErrorMessage] = useState(""); | ||
|
||
/* Callback to set album purchase details */ | ||
const setEquipmentPurchaseDetails = useCallback( | ||
async (e) => { | ||
// Prevent the default action associated with the click event | ||
e.preventDefault(); | ||
|
||
// Construct the values to be passed to the API | ||
const updatedPurchaseDate = | ||
equipment.isWishListItem != true ? purchaseDate : null; | ||
const updatedPrice = price != undefined ? price : null; | ||
const updatedRetailerId = retailer != null ? retailer.id : null; | ||
|
||
// Apply the updates | ||
const updatedEquipment = await apiSetEquipmentPurchaseDetails( | ||
equipment, | ||
updatedPurchaseDate, | ||
updatedPrice, | ||
updatedRetailerId, | ||
logout | ||
); | ||
|
||
// If the returned album is valid, navigate back to the albums by artist page. | ||
// Otherwise, show an error | ||
if (updatedEquipment != null) { | ||
navigate({ | ||
page: pages.equipment, | ||
isWishList: updatedEquipment.isWishListItem, | ||
}); | ||
} else { | ||
setErrorMessage("Error updating the equipment purchase details"); | ||
} | ||
}, | ||
[equipment, price, purchaseDate, retailer, logout, navigate] | ||
); | ||
|
||
return ( | ||
<> | ||
<div className="row mb-2 pageTitle"> | ||
<h5 className="themeFontColor text-center"> | ||
{equipment.description} - Purchase Details | ||
</h5> | ||
</div> | ||
<div className={styles.purchaseDetailsFormContainer}> | ||
<form className={styles.purchaseDetailsForm}> | ||
<div> | ||
{equipment.isWishListItem == true ? ( | ||
<></> | ||
) : ( | ||
<div className="form-group mt-3"> | ||
<label className={styles.purchaseDetailsFormLabel}> | ||
Purchase Date | ||
</label> | ||
<div> | ||
<DatePicker | ||
selected={purchaseDate} | ||
onChange={(date) => setPurchaseDate(date)} | ||
/> | ||
</div> | ||
</div> | ||
)} | ||
<div className="form-group mt-3"> | ||
<label className={styles.purchaseDetailsFormLabel}>Price</label> | ||
<div> | ||
<CurrencyInput | ||
placeholder="Price" | ||
name="price" | ||
defaultValue={price} | ||
decimalsLimit={2} | ||
allowNegativeValue={false} | ||
disableAbbreviations={true} | ||
intlConfig={{ | ||
locale: config.region.locale, | ||
currency: config.region.currency, | ||
}} | ||
onValueChange={(value, _) => setPrice(value)} | ||
/> | ||
</div> | ||
</div> | ||
<div className="form-group mt-3"> | ||
<label className={styles.purchaseDetailsFormLabel}> | ||
Retailer | ||
</label> | ||
<div> | ||
<RetailerSelector | ||
initialRetailer={retailer} | ||
retailerChangedCallback={setRetailer} | ||
logout={logout} | ||
/> | ||
</div> | ||
</div> | ||
<div className="d-grid gap-2 mt-3"> | ||
<span className={styles.purchaseDetailsError}> | ||
{errorMessage} | ||
</span> | ||
</div> | ||
<div className="d-grid gap-2 mt-3"></div> | ||
<div className="d-grid gap-2 mt-3"></div> | ||
<div className={styles.purchaseDetailsButton}> | ||
<button | ||
className="btn btn-primary" | ||
onClick={(e) => setEquipmentPurchaseDetails(e)} | ||
> | ||
Save | ||
</button> | ||
</div> | ||
<div className={styles.purchaseDetailsButton}> | ||
<button | ||
className="btn btn-primary" | ||
onClick={() => | ||
navigate({ | ||
page: pages.albums, | ||
artist: artist, | ||
album: equipment, | ||
isWishList: equipment.isWishListItem, | ||
}) | ||
} | ||
> | ||
Cancel | ||
</button> | ||
</div> | ||
</div> | ||
</form> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default EquipmentPurchaseDetails; |
Oops, something went wrong.